package cn.funnymap.lgis.params.validation;

import cn.funnymap.lgis.params.DateRange;
import cn.funnymap.lgis.utils.DateUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.util.Date;

/**
 * 日期范围参数校验器，仅支持对yyyy-MM-dd格式的字符串日期进行解析
 *
 * @author jiaoxn
 */
@ConditionalOnClass(Constraint.class)
public class DateRangeValidator implements ConstraintValidator<DateRangeValidation, Object> {
    @Override
    public void initialize(DateRangeValidation constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        // 如果对象值为空，则验证通过
        if (value == null) {
            return true;
        }

        if (value instanceof DateRange) {
            DateRange dateRange = (DateRange) value;
            String startDate = dateRange.getStart();
            String endDate = dateRange.getEnd();

            if (startDate == null || endDate == null) {
                // 如果日期范围对象有值，则起始日期和结束日期均不能为空
                replaceErrorMessage(context, "起始日期或结束日期不能为空");

                return false;
            } else {
                try {
                    Date start = DateUtil.str2Date(startDate);
                    Date end = DateUtil.str2Date(endDate);

                    // 如果起始日期不早于结束日期，表示校验失败
                    if (start.after(end)) {
                        replaceErrorMessage(context, "起始日期不能晚于结束日期");
                        return false;
                    }
                } catch (ParseException e) {
                    // 如果日期格式不正确，表示校验失败
                    replaceErrorMessage(context, "起始日期或结束日期格式不正确，请确保格式为yyyy-MM-dd");
                    return false;
                }
            }
        }

        return true;
    }
    private void replaceErrorMessage(ConstraintValidatorContext context, String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
    }
}
